package mobisocial.nfc.legacy;
import org.json.JSONArray;
import org.json.JSONException;
import com.android.apps.tag.record.UriRecord;
import mobisocial.ndefexchange.PendingNdefExchange;
import mobisocial.nfc.ConnectionHandoverManager;
import mobisocial.nfc.NdefHandler;
import mobisocial.nfc.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
/**
* An inefficient but functional activity for storing devices'
* names and NDEF handover addresses.
*
*/
public class FriendsActivity extends ListActivity {
private static final String TAG = "friendDef";
private static final int ADD_FRIEND_QR = 0;
private static final int DIALOG_NAME = 0;
private SharedPreferences mPreferences;
private String mScannedNdefString;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPreferences = getSharedPreferences("main", 0);
setContentView(R.layout.friends);
setListAdapter(getFriendsListAdapter());
findViewById(R.id.add_friend).setOnClickListener(mAddFriend);
}
View.OnClickListener mAddFriend = new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
try {
startActivityForResult(intent, ADD_FRIEND_QR);
} catch (Exception e) {
toast("Please install the barcode scanner.");
}
}
};
private NdefHandler mNdefHandler = new NdefHandler() {
@Override
public int handleNdef(NdefMessage[] ndefMessages) {
startActivityForNdef(ndefMessages);
return NDEF_CONSUME;
}
};
private void startActivityForNdef(NdefMessage[] ndefMessages) {
NdefRecord firstRecord = ndefMessages[0].getRecords()[0];
Log.d(TAG, "DISCOVERED NDEF " + new String(firstRecord.getPayload()));
if (UriRecord.isUri(firstRecord)) {
UriRecord uriRecord = UriRecord.parse(firstRecord);
Intent intent = new Intent(NfcAdapter.ACTION_NDEF_DISCOVERED, uriRecord.getUri());
intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, ndefMessages);
if (null == getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)) {
toast("Could not handle ndef.");
return;
}
startActivity(intent);
} else {
toast("Ndef launching needs work.");
}
}
protected void onListItemClick(ListView l, View v, int position, long id) {
toast("Grabbing NDEF content...");
NdefMessage handover = getHandover(position);
new PendingNdefExchange(handover, mNdefHandler).exchangeNdef(null);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == ADD_FRIEND_QR) {
if (resultCode == Activity.RESULT_OK) {
try {
String data = intent.getStringExtra("SCAN_RESULT");
if (!data.startsWith(ConnectionHandoverManager.USER_HANDOVER_PREFIX)) {
throw new Exception();
}
// make sure it parses
new NdefMessage(android.util.Base64.decode(
data.substring(ConnectionHandoverManager.USER_HANDOVER_PREFIX.length()),
android.util.Base64.URL_SAFE));
mScannedNdefString = data.substring(ConnectionHandoverManager.USER_HANDOVER_PREFIX.length());
showDialog(DIALOG_NAME);
} catch (Exception e) {
toast("QR code is not a vNFC tag.");
}
}
}
}
// TODO: Proper backend.
private ListAdapter getFriendsListAdapter() {
String[] mItems;
String namesStr = mPreferences.getString("names", null);
if (namesStr == null) {
mItems = new String[0];
} else {
try {
JSONArray arr = new JSONArray(namesStr);
mItems = new String[arr.length()];
for (int i = 0; i < arr.length(); i++) {
mItems[i] = arr.getString(i);
}
} catch (JSONException e) {
mItems = new String[0];
}
}
return new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mItems);
}
private void saveFriend(String name, String handoverStr) {
try {
JSONArray names;
JSONArray handovers;
String namesStr = mPreferences.getString("names", null);
String handoversStr = mPreferences.getString("handovers", null);
if (namesStr == null) {
names = new JSONArray();
handovers = new JSONArray();
} else {
names = new JSONArray(namesStr);
handovers = new JSONArray(handoversStr);
}
names.put(name);
handovers.put(handoverStr);
Editor edit = mPreferences.edit();
edit.putString("names", names.toString());
edit.putString("handovers", handovers.toString());
edit.commit();
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
private NdefMessage getHandover(int pos) {
String listStr = mPreferences.getString("handovers", null);
if (listStr == null) {
return null;
}
try {
JSONArray handovers = new JSONArray(listStr);
if (handovers.length() <= pos) {
return null;
}
String handoverStr = handovers.getString(pos);
return new NdefMessage(android.util.Base64.decode(handoverStr, android.util.Base64.URL_SAFE));
} catch (FormatException e) {
throw new IllegalArgumentException(e);
} catch (JSONException e) {
throw new IllegalArgumentException(e);
}
}
protected Dialog onCreateDialog(int id) {
Dialog dialog;
switch(id) {
case DIALOG_NAME:
final EditText input = new EditText(this);
dialog = new AlertDialog.Builder(this)
.setTitle("Enter name")
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
saveFriend(input.getText().toString(), mScannedNdefString);
setListAdapter(getFriendsListAdapter());
mScannedNdefString = null;
} catch (Exception e) {
toast("Error parsing qr code.");
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mScannedNdefString = null;
}
})
.setView(input)
.create();
break;
default:
dialog = null;
}
return dialog;
}
private void toast(final String text) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(FriendsActivity.this, text, Toast.LENGTH_LONG).show();
}
});
}
}